﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Scripting;
using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Hosting;

using DlrBasic;
using DlrBasic.Runtime;
using Microsoft.Scripting.Generation;
using Microsoft.Scripting.Utils;

namespace DlrBasicTest
{
    class Program
    {
        const string BasicCode =
            "5 PRINT \"SQUARE EQUATION CALCULATOR: A*X^2+B*X+C=0\"\r\n" + 
            "10 INPUT \"ENTER A,B,C\";A,B,C\r\n" +
            "20 D=B*B-4*A*C\r\n" +
            "30 IF D<0 THEN PRINT \"NO SOLUTIONS\": GOTO 90\r\n" +
            "40 IF D>0 THEN 70\r\n" +
            "50 X=-B/(2*A): PRINT \"ONE SOLUTION. X=\";X\r\n" +
            "60 GOTO 90\r\n" +
            "70 X1=(-B-SQR(D))/(2*A):X2=(-B+SQR(D))/(2*A)\r\n" +
            "80 PRINT \"TWO SOLUTIONS. X1=\"X1\", X2=\"X2\r\n" +
            "90 END";

        static void Main(string[] args)
        {
            ScriptRuntime runtime = ScriptRuntime.CreateFromConfiguration();            
            ScriptEngine engine = runtime.GetEngine("DlrBasic");

            ScriptScope scope = engine.CreateScope();
            //scope.SetVariable("statementCallback", new StatementCallback(TestCallback));

            ScriptSource source = engine.CreateScriptSourceFromString(BasicCode);            
            source.Execute(scope);

        }

        static StatementExecutionAction TestCallback(CodeContext context, DlrBasicState state)
        {
            if (state.StatementName == "Print")
            {
                switch (state.LineNumber)
                {
                    case 30:
                        Console.WriteLine("NEW: No solutions");
                        break;
                    case 50:
                        Console.WriteLine("NEW: One solution: {0}",
                            state.Memory["X"]);
                        break;
                    case 80:
                        Console.WriteLine("NEW: Two solutions: {0}, {1}",
                            state.Memory["X1"], state.Memory["X2"]);
                        break;
                }
                return StatementExecutionAction.Ignore;
            }
            else if (state.StatementName == "Input")
            {
                state.Memory["A"] = 2f;
                state.Memory["B"] = 0f;
                state.Memory["C"] = -8f;
                return StatementExecutionAction.Ignore;
            }
            else
                return StatementExecutionAction.Execute;
        }
    }
}
